const fs = require("fs");
const path = require("path");

const fileUtil = {
    /**
     * 获取文件夹下的所有文件
     * @param {string | Buffer |URL} directory 文件夹
     */
    getFilesInDirectory(directory) {
        return new Promise((resolve, reject) => {
            fs.readdir(directory, async (error, files) => {
                if (error) {
                    return reject(error);
                }
                let resArr = [];
                // 获取完整路径
                const fullPathFiles = files.map(file => path.join(directory, file));
                for (let fullPathFile of fullPathFiles) {
                    if (fs.statSync(fullPathFile).isDirectory()) {
                        const res = await this.getFilesInDirectory(fullPathFile);
                        if (res) {
                            resArr = resArr.concat(res);
                        }
                    } else {
                        resArr.push(fullPathFile);
                    }
                }
                resolve(resArr);
            });
        });
    },
    /**
     * 判断文件是否存在
     * @param {string | Buffer |URL} file 文件
     * @returns {boolean}
     */
    isExist(file) {
        return fs.existsSync(file);
    },
    /**
     * 将文件路径解析为文件名
     * @param filePath 文件路径
     * @return {string}
     */
    relVueName(filePath) {
        return filePath.split(path.sep).pop().replace('.vue', '');
    },
    // 转驼峰
    toHump(str) {
        const spacers = ['-', '_'];
        return str.replace(new RegExp('[' + spacers.join('|') + '](\\w)', 'g'), (_, c) => c ? c.toUpperCase() : '');
    },
    getVueFileNameKey(filePath) {
        return this.toHump(this.relVueName(filePath))
    },
    /**
     * 获取Vue文件
     * @param {string | Buffer |URL} directory 文件夹
     * @param {(filePath: string, content: string, fileStats: Stats) => void} cb 回调
     * @return {Promise<void>}
     */
    async getVueFiles(directory, cb) {
        await this.getFilesInDirectory(directory).then(files => {
            // 过滤掉非 vue 文件
            files = files.filter(file => file.split('.').pop() === 'vue');
            for (let file of files) {
                const fileStats = fs.statSync(file);
                const content = fs.readFileSync(file).toString();
                cb && cb(file, content, fileStats);
            }
        });
    },
    /**
     * 保存文件
     * @param {string | NodeJS.ArrayBufferView} content 文件内容
     * @param {string} filePath 文件路径
     */
    saveFile(content, filePath) {
        fs.writeFileSync(filePath, content, {
            encoding: 'utf-8'
        });
    },
    replaceAtPrefix(filePath) {
        if (filePath.startsWith('@/')) {
            return path.resolve(__dirname, filePath.substr(2));
        }
        return filePath;
    }
}

exports.fileUtil = fileUtil
